home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1996-03-24 | 26.5 KB | 755 lines |
- Syntax10.Scn.Fnt
- Syntax10b.Scn.Fnt
- ParcElems
- Alloc
- Syntax10i.Scn.Fnt
- MODULE PSPrinter;
- (* JT 11.5.90, RC 2.7.93, JS 13.10.94, SHML 12 Jul 95, Amiga RD 30 Oct 95, PSFonts RD 3 Dec 95,
- PSFonts again hG 23 Jan 94, Pictures rewritten RD 24.3.96 *)
- IMPORT SYSTEM, PrinterDriver, Files, Texts, Oberon, Kernel, Amiga, Pictures, Display;
- CONST
- N = 20;
- maxFonts = 64;
- DefaultResolution = 300;
- defaultHeaderFileName = "Oberon.Header.ps";
- CR = 0DX; LF = 0AX;
- NrPSFonts = 3;
- normal=0; bold=1; italic=2; magic=3;
- TYPE
- Name = ARRAY 32 OF CHAR;
- FontDesc = RECORD
- name: Name;
- used: ARRAY 8 OF SET
- END;
- RealVector = ARRAY N OF REAL;
- Poly = RECORD a, b, c, d, t: REAL END ;
- PolyVector = ARRAY N OF Poly;
- headerFileName, printFileName: Name;
- fontTable: ARRAY maxFonts OF FontDesc;
- fontIndex, curFont: INTEGER;
- listFont: Name;
- headerF, bodyF: Files.File;
- bodyR: Files.Rider;
- pno, ppos, plen: LONGINT;
- hexArray: ARRAY 17 OF CHAR;
- curR, curG, curB: INTEGER;
- resolution: INTEGER;
- FontsToMap: ARRAY NrPSFonts OF ARRAY 10 OF CHAR; (* PSFonts know to Oberon.Header.ps *)
- styleNames: ARRAY 4 OF ARRAY 10 OF CHAR;
- recodedPSFonts: ARRAY NrPSFonts OF SET;
- PROCEDURE IncPrintFile(VAR name:ARRAY OF CHAR);
- i:INTEGER;
- BEGIN
- i:=0; WHILE name[i]#0X DO INC(i) END;
- a i-5
- a i-4
- . i-3
- p i-2
- s i-1
- i:=i-4;
- name[i]:=CHR(ORD(name[i])+1);
- IF (name[i]>"z") THEN
- name[i]:="a";
- name[i-1]:=CHR(ORD(name[i-1])+1);
- IF (name[i-1]>"z") THEN
- name[i-1]:="a"
- END
- END
- END IncPrintFile;
- PROCEDURE Append(VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR);
- VAR i, j: INTEGER; ch: CHAR;
- BEGIN i := 0; j := 0;
- WHILE s1[i] # 0X DO INC(i) END ;
- REPEAT ch := s2[j]; s1[i] := ch; INC(i); INC(j) UNTIL ch = 0X
- END Append;
- PROCEDURE ScanFirst(VAR s: Texts.Scanner); (* Scan first parameter *)
- VAR sel: Texts.Text; beg, end, time: LONGINT;
- BEGIN
- Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s);
- IF (s.class = Texts.Char) & (s.line = 0) & (s.c = "^") THEN
- Oberon.GetSelection(sel, beg, end, time);
- IF time >= 0 THEN Texts.OpenScanner(s, sel, beg); Texts.Scan(s) ELSE s.class := Texts.Inval END
- END
- END ScanFirst;
- (* -- Output procedures -- *)
- PROCEDURE Ch (VAR R: Files.Rider; ch: CHAR);
- BEGIN Files.Write(R, ch)
- END Ch;
- PROCEDURE Str (VAR R: Files.Rider; s: ARRAY OF CHAR);
- VAR i: INTEGER;
- BEGIN
- i := 0;
- WHILE s[i] # 0X DO Ch(R, s[i]); INC(i) END
- END Str;
- PROCEDURE Int (VAR R: Files.Rider; i: LONGINT);
- VAR j: LONGINT;
- BEGIN
- IF i = 0 THEN Ch(R, "0") ELSIF i < 0 THEN i := -i; Ch(R, "-") END;
- j := 1;
- WHILE (i DIV j) # 0 DO j := j * 10 END;
- WHILE j >= 10 DO j := j DIV 10; Ch(R, CHR(ORD("0") + (i DIV j) MOD 10)) END
- END Int;
- PROCEDURE Hex(VAR R: Files.Rider; i: INTEGER);
- BEGIN
- IF i < 10 THEN Ch(R, CHR(i+ORD("0")))
- ELSE Ch(R, CHR(i+(ORD("a")-10)))
- END
- END Hex;
- PROCEDURE Hex2(VAR R: Files.Rider; ch: CHAR);
- BEGIN
- Ch(R, hexArray[ORD(ch) DIV 16]);
- Ch(R, hexArray[ORD(ch) MOD 16])
- END Hex2;
- PROCEDURE Ln(VAR R: Files.Rider);
- BEGIN
- Ch(R, 0AX)
- END Ln;
- (* -- Font Mapping -- *)
- PROCEDURE SetBitmapFont(VAR fontR, R: Files.Rider; fd: FontDesc; pRes: INTEGER);
- CONST fontFileId = 0DBX;
- TYPE
- RunRec = RECORD beg, end: INTEGER END;
- Metrics = RECORD dx, x, y, w, h: INTEGER END;
- VAR
- ch: CHAR;
- pixmapDX, n, b: LONGINT;
- k, m: INTEGER;
- height, minX, maxX, minY, maxY: INTEGER;
- nOfBoxes, nOfRuns: INTEGER;
- run: ARRAY 16 OF RunRec;
- metrics: ARRAY 256 OF Metrics;
- PROCEDURE Flip(ch: CHAR): CHAR;
- VAR i, s, d: INTEGER;
- BEGIN
- i := 0; s := ORD(ch); d := 0;
- WHILE i < 8 DO
- IF s MOD 2 = 1 THEN d := d * 2 + 1 ELSE d := d * 2 END;
- s := s DIV 2;
- INC(i)
- END;
- RETURN CHR(d)
- END Flip;
- PROCEDURE Name(m: INTEGER);
- BEGIN
- CASE m OF
- | 9: Str(fontR, "tab")
- | 32: Str(fontR, "space")
- | 33: Str(fontR, "exclam")
- | 34: Str(fontR, "quotedbl")
- | 35: Str(fontR, "numbersign")
- | 36: Str(fontR, "dollar")
- | 37: Str(fontR, "percent")
- | 38: Str(fontR, "ampersand")
- | 39: Str(fontR, "quotesingle")
- | 40: Str(fontR, "parenleft")
- | 41: Str(fontR, "parenright")
- | 42: Str(fontR, "asterisk")
- | 43: Str(fontR, "plus")
- | 44: Str(fontR, "comma")
- | 45: Str(fontR, "minus")
- | 46: Str(fontR, "period")
- | 47: Str(fontR, "slash")
- | 48: Str(fontR, "zero")
- | 49: Str(fontR, "one")
- | 50: Str(fontR, "two")
- | 51: Str(fontR, "three")
- | 52: Str(fontR, "four")
- | 53: Str(fontR, "five")
- | 54: Str(fontR, "six")
- | 55: Str(fontR, "seven")
- | 56: Str(fontR, "eight")
- | 57: Str(fontR, "nine")
- | 58: Str(fontR, "colon")
- | 59: Str(fontR, "semicolon")
- | 60: Str(fontR, "less")
- | 61: Str(fontR, "equal")
- | 62: Str(fontR, "greater")
- | 63: Str(fontR, "question")
- | 64: Str(fontR, "at")
- | 65..90: Ch(fontR, CHR(m))
- | 91: Str(fontR, "bracketleft")
- | 92: Str(fontR, "backslash")
- | 93: Str(fontR, "bracketright")
- | 94: Str(fontR, "arrowup")
- | 95: Str(fontR, "underscore")
- | 96: Str(fontR, "grave")
- | 97..122: Ch(fontR, CHR(m))
- | 123: Str(fontR, "braceleft")
- | 124: Str(fontR, "bar")
- | 125: Str(fontR, "braceright")
- | 126: Str(fontR, "tilde")
- | 128: Str(fontR, "Adieresis")
- | 129: Str(fontR, "Odieresis")
- | 130: Str(fontR, "Udieresis")
- | 131: Str(fontR, "adieresis")
- | 132: Str(fontR, "odieresis")
- | 133: Str(fontR, "udieresis")
- | 134: Str(fontR, "acircumflex")
- | 135: Str(fontR, "ecircumflex")
- | 136: Str(fontR, "icircumflex")
- | 137: Str(fontR, "oicircumflex")
- | 138: Str(fontR, "uicircumflex")
- | 139: Str(fontR, "agrave")
- | 140: Str(fontR, "egrave")
- | 141: Str(fontR, "igrave")
- | 142: Str(fontR, "ograve")
- | 143: Str(fontR, "ugrave")
- | 144: Str(fontR, "eacute")
- | 145: Str(fontR, "edieresis")
- | 146: Str(fontR, "idieresis")
- | 147: Str(fontR, "ccedilla")
- | 148: Str(fontR, "aacute")
- | 149: Str(fontR, "ntilde")
- | 155: Str(fontR, "endash")
- | 159: Str(fontR, "hyphen")
- | 171: Str(fontR, "germandbls")
- ELSE
- Str(fontR, "ascii");
- Ch(fontR, CHR(ORD("0") + (m DIV 100) MOD 10));
- Ch(fontR, CHR(ORD("0") + (m DIV 10) MOD 10));
- Ch(fontR, CHR(ORD("0") + m MOD 10))
- END
- END Name;
- BEGIN
- Str(fontR, "% Conversion of the Oberon font "); Str(fontR, fd.name); Ln(fontR);
- Files.Read(R, ch);
- IF ch = fontFileId THEN
- Files.Read(R, ch); Str(fontR, "% abstraction: "); Int(fontR, ORD(ch));
- Files.Read(R, ch); Str(fontR, ", family: "); Ch(fontR, ch);
- Files.Read(R, ch); Str(fontR, ", variant: "); Int(fontR, ORD(ch)); Ln(fontR);
- Files.ReadInt(R, height); Str(fontR, "% height: "); Int(fontR, height); Ln(fontR); Ln(fontR);
- Files.ReadInt(R, minX); Files.ReadInt(R, maxX);
- Files.ReadInt(R, minY); Files.ReadInt(R, maxY);
- Files.ReadInt(R, nOfRuns);
- nOfBoxes := 0; k := 0;
- WHILE k # nOfRuns DO
- Files.ReadInt(R, run[k].beg); Files.ReadInt(R, run[k].end);
- INC(nOfBoxes, run[k].end - run[k].beg);
- INC(k)
- END;
- Str(fontR, "9 dict begin"); Ln(fontR); Ln(fontR);
- Str(fontR, "/FontType 3 def"); Ln(fontR);
- Str(fontR, "/FontMatrix [ 72 "); Int(fontR, pRes); Str(fontR, " div "); Str(fontR, " .24 div 0 0 ");
- Str(fontR, "72 "); Int(fontR, pRes); Str(fontR, " div "); Str(fontR, " .24 div 0 0");
- Str(fontR, "] def"); Ln(fontR);
- Str(fontR, "/FontBBox [");
- Int(fontR, minX); Ch(fontR, " ");
- Int(fontR, minY); Ch(fontR, " ");
- Int(fontR, maxX); Ch(fontR, " ");
- Int(fontR, maxY);
- Str(fontR, "] def"); Ln(fontR);
- (* hG/23-Jan-1996
- Str(fontR, "/Encoding 256 array def"); Ln(fontR);
- Str(fontR, "0 1 255 {Encoding exch /.notdef put} for"); Ln(fontR);
- Str(fontR, "Encoding OberonEncoding OberonXEncoding OberonYEncoding /Encoding exch def"); Ln(fontR);
- Ln(fontR);
- Str(fontR, "/Encoding FullOberonEncoding def"); Ln(fontR); Ln(fontR); (* hG/23-Jan-1996 *)
- Str(fontR, "/CharData "); Int(fontR, nOfBoxes+1);
- Str(fontR, " dict def"); Ln(fontR);
- Str(fontR, "CharData begin"); Ln(fontR);
- k := 0; m := 0;
- WHILE k < nOfRuns DO
- m := run[k].beg;
- WHILE m < run[k].end DO
- Files.ReadInt(R, metrics[m].dx);
- Files.ReadInt(R, metrics[m].x); Files.ReadInt(R, metrics[m].y);
- Files.ReadInt(R, metrics[m].w); Files.ReadInt(R, metrics[m].h);
- INC(m)
- END;
- INC(k)
- END;
- Str(fontR, "/.notdef"); Str(fontR, " [");
- Int(fontR, metrics[32].w); Str(fontR, " 0 0 0 0 1 1 0 0"); Ln(fontR);
- Str(fontR, "<>] bdef"); Ln(fontR);
- k := 0; m := 0;
- WHILE k < nOfRuns DO
- m := run[k].beg;
- WHILE m < run[k].end DO
- IF m MOD 32 IN fd.used[m DIV 32] THEN
- Str(fontR, "/"); Name(m); Str(fontR, " [");
- Int(fontR, metrics[m].dx); Str(fontR, " ");
- Int(fontR, metrics[m].x); Str(fontR, " "); Int(fontR, metrics[m].y); Str(fontR, " ");
- Int(fontR, metrics[m].x + metrics[m].w); Str(fontR, " ");
- Int(fontR, metrics[m].y + metrics[m].h); Str(fontR, " ");
- IF metrics[m].w > 0 THEN Int(fontR, metrics[m].w) ELSE Int(fontR, 1) END; Str(fontR, " ");
- IF metrics[m].h > 0 THEN Int(fontR, metrics[m].h) ELSE Int(fontR, 1) END; Str(fontR, " ");
- Int(fontR, -metrics[m].x); Str(fontR, " "); Int(fontR, -metrics[m].y); Ln(fontR);
- Str(fontR, "<");
- pixmapDX := (metrics[m].w + 7) DIV 8;
- n := pixmapDX * metrics[m].h;
- b := 0;
- WHILE b < n DO
- Files.Read(R, ch); Hex2(fontR, Flip(ch));
- INC(b);
- IF b MOD 32 = 0 THEN Ln(fontR); Str(fontR, " ") END
- END;
- Str(fontR, ">] bdef"); Ln(fontR)
- ELSE
- n := (metrics[m].w + 7) DIV 8 * metrics[m].h;
- b := 0; WHILE b < n DO Files.Read(R, ch); INC(b) END
- END;
- INC(m)
- END;
- INC(k)
- END;
- Str(fontR, " end"); Ln(fontR); Ln(fontR);
- Str(fontR, "/BuildGlyph {GlobalBuildGlyph} bdef"); Ln(fontR);
- Str(fontR, "/BuildChar {GlobalBuildChar} bdef"); Ln(fontR); Ln(fontR);
- Str(fontR, "/imageMaskMatrix [1 0 0 1 0 0] bdef"); Ln(fontR); Ln(fontR);
- Str(fontR, "currentdict"); Ln(fontR); Ln(fontR);
- Str(fontR, "end"); Ln(fontR); Ln(fontR);
- Ch(fontR, "/"); Str(fontR, fd.name); Ch(fontR, "D");
- Str(fontR, " exch definefont pop");
- Ln(fontR); Ch(fontR, "/"); Str(fontR, fd.name); Str(fontR, " {/"); Str(fontR, fd.name); Str(fontR, "D f} bdef");
- Ln(fontR); Ln(fontR)
- END
- END SetBitmapFont;
- PROCEDURE SetPSFont(VAR R: Files.Rider; n: ARRAY OF CHAR): BOOLEAN;
- VAR PSFont, Pos, Typ, w: INTEGER;
- (* Search for Font in Mapping List *)
- PROCEDURE TestPSFont(VAR Name: ARRAY OF CHAR; VAR PSFont, Pos: INTEGER);
- VAR i, j: INTEGER;
- BEGIN
- FOR i:=0 TO NrPSFonts-1 DO
- j:=-1;
- REPEAT
- INC(j);
- IF FontsToMap[i,j]=CHR(0) THEN Pos:=j; PSFont:=i; RETURN END
- UNTIL Name[j]#FontsToMap[i,j]
- END;
- Pos:=-1
- END TestPSFont;
- BEGIN
- TestPSFont(n, PSFont, Pos);
- IF Pos<0 THEN RETURN FALSE END; (* entry in mapping list ? no => FALSE *)
- w:=0;
- WHILE (ORD(n[Pos])<58) & (ORD(n[Pos])>=48) DO w:=w*10+ORD(n[Pos])-48; INC(Pos) END;
- CASE n[Pos] OF
- | ".": Typ:= normal
- | "b": Typ:= bold
- | "i": Typ:= italic
- | "m": Typ:= magic
- ELSE
- Typ:= normal
- END;
- IF ~ (Typ IN recodedPSFonts[PSFont]) THEN
- INCL(recodedPSFonts[PSFont], Typ);
- Str(R, "/Ob-"); Str(R, FontsToMap[PSFont]); Str (R, styleNames[Typ]); Str(R, " ");
- Str(R, FontsToMap[PSFont]); Str(R, styleNames[Typ]); Str(R, ".Fnt recode"); Ln(R);
- END;
- Ch(R, "/"); Str(R, n); Str(R, " {/Ob-"); Str(R, FontsToMap[PSFont]); Str (R, styleNames[Typ]); Str(R, " ");
- Int(R, w); Str(R, " "); Str(R, FontsToMap[PSFont]); Str(R, "-ScaleFactor MF} bdef"); Ln(R); Ln(R);
- RETURN TRUE
- END SetPSFont;
- PROCEDURE DefineFont(VAR fontR: Files.Rider; fd: FontDesc);
- VAR name: ARRAY 32 OF CHAR; i, size: INTEGER; VAR f: Files.File; R: Files.Rider;
- BEGIN
- COPY(fd.name, name); i := 0; size := 0;
- WHILE (name[i] # 0X) & (name[i] # ".") & ((name[i] < "0") OR (name[i] > "9")) DO INC(i) END;
- WHILE (name[i] >= "0") & (name[i] <= "9") DO size := size * 10 + ORD(name[i]) - ORD("0"); INC(i) END;
- WHILE (name[i] # 0X) & (name[i] # ".") DO INC(i) END;
- IF (name[i] # ".") OR (name[i+1] # "S") OR (name[i+2] #"c") OR (name[i+3] # "n") THEN
- PrinterDriver.Error(name, " illegal font name")
- ELSE
- name[i+1] := "P"; name[i+2] := "r"; name[i+3] := "3";
- f := Files.Old(name);
- IF f = NIL THEN
- IF ~SetPSFont(fontR, fd.name) THEN PrinterDriver.Error(name, " font missing and can not find PS font") END
- ELSE
- Files.Set(R, f, 0); SetBitmapFont(fontR, R, fd, resolution)
- END
- END
- END DefineFont;
- (* -- Printing Procedures -- *)
- PROCEDURE Open(VAR name, user: ARRAY OF CHAR; password: LONGINT);
- BEGIN
- curR := 0; curG := 0; curB := 0;
- PrinterDriver.res := 0; PrinterDriver.err := FALSE;
- resolution := DefaultResolution; (* COPY(name, printFileName); *)
- i := -1;
- REPEAT INC(i); printFileName[i] := name[i] UNTIL printFileName[i] = 0X;
- resolution := 0; mul := 1;
- LOOP
- DEC(i); ch := name[i];
- IF (i = 0) OR (ch = ".") THEN printFileName[i] := 0X; EXIT END;
- IF ("0" <= ch) & (ch <= "9") THEN INC(resolution, mul*(ORD(ch)-ORD("0"))); mul := 10*mul
- ELSE printFileName[i+1] := 0X; resolution := DefaultResolution; EXIT
- END
- END;
- headerF := Files.Old(headerFileName);
- IF headerF # NIL THEN
- bodyF := Files.New(""); Files.Set(bodyR, bodyF, 0);
- recodedPSFonts[0] := {}; recodedPSFonts[1] := {}; recodedPSFonts[2] := {};
- fontIndex := -1; curFont := -1; listFont := ""; ppos := 0; pno := 1
- ELSE
- PrinterDriver.Error("file not found", headerFileName)
- END
- END Open;
- PROCEDURE UseListFont(VAR name: ARRAY OF CHAR);
- BEGIN
- COPY(name, listFont); curFont := -1
- END UseListFont;
- PROCEDURE ReplConst(x, y, w, h: INTEGER);
- BEGIN
- IF (w > 0) & (h > 0) THEN
- Int(bodyR, x+1); Ch(bodyR, " ");
- Int(bodyR, y); Ch(bodyR, " ");
- Int(bodyR, w-1); Ch(bodyR, " ");
- Int(bodyR, h-1); Str(bodyR, " l"); Ln(bodyR)
- END
- END ReplConst;
- PROCEDURE ContString(VAR s, fname: ARRAY OF CHAR);
- VAR fNo, i, n: INTEGER; ch: CHAR; family: ARRAY 7 OF CHAR; fontName: ARRAY 32 OF CHAR;
- PROCEDURE Use(ch: CHAR);
- BEGIN
- INCL(fontTable[curFont].used[ORD(ch) DIV 32], ORD(ch) MOD 32)
- END Use;
- BEGIN
- IF fname = listFont THEN fontName := "Courier8.Scn.Fnt" ELSE COPY (fname, fontName) END;
- IF (curFont < 0) OR (fontTable[curFont].name # fontName) THEN
- COPY(fontName, fontTable[fontIndex+1].name);
- i := 0; WHILE i < 8 DO fontTable[fontIndex+1].used[i] := {}; INC(i) END;
- fNo := 0;
- WHILE fontTable[fNo].name # fontName DO INC(fNo) END;
- IF fNo > fontIndex THEN (* DefineFont(fontName); *) fontIndex := fNo END;
- curFont := fNo;
- Str(bodyR, fontTable[curFont].name); Ch(bodyR, " ")
- (* something killed here *)
- END;
- Ch(bodyR, "(");
- i := 0; ch := s[0];
- WHILE ch # 0X DO
- CASE ch OF
- | "(", ")", "\": Ch(bodyR, "\"); Ch(bodyR, ch); Use(ch)
- | 9X: Str(bodyR, " "); Use(" ") (* or Str("\tab") *)
- | 80X..95X, 0ABX:
- Str(bodyR, "\2"); n := ORD(ch)-128;
- Ch(bodyR, CHR(n DIV 8 + 48)); Ch(bodyR, CHR(n MOD 8 + 48)); Use(ch)
- | 9FX: COPY(fontTable[curFont].name, family);
- IF family = "Courie" THEN Ch(bodyR, " ") ELSE Str(bodyR, " ") END; Use(" ")
- ELSE
- IF (ORD(ch) >= 32) & (ORD(ch) < 127) THEN
- Ch(bodyR, ch)
- ELSE
- Ch(bodyR, "\");
- Ch(bodyR, CHR((ORD(ch) DIV 64) MOD 8 + ORD("0")));
- Ch(bodyR, CHR((ORD(ch) DIV 8) MOD 8 + ORD("0")));
- Ch(bodyR, CHR(ORD(ch) MOD 8 + ORD("0")))
- END;
- Use(ch)
- END ;
- INC(i); ch := s[i]
- END;
- Str(bodyR, ") s"); Ln(bodyR)
- END ContString;
- PROCEDURE String(x, y: INTEGER; VAR s, fname: ARRAY OF CHAR);
- BEGIN
- Int(bodyR, x); Ch(bodyR, " ");
- Int(bodyR, y); Str(bodyR, " m "); ContString(s, fname)
- END String;
- PROCEDURE ReplPattern(x, y, w, h, col: INTEGER);
- BEGIN
- Int(bodyR, x+1); Ch(bodyR, " ");
- Int(bodyR, y); Ch(bodyR, " ");
- Int(bodyR, w-1); Ch(bodyR, " ");
- Int(bodyR, h-1); Ch(bodyR, " ");
- Int(bodyR, col); Str(bodyR, " b"); Ln(bodyR)
- END ReplPattern;
- (* rewritten by RD 24.3.1996 *)
- PROCEDURE Picture(x, y, w, h, mode: INTEGER; adr: LONGINT);
- VAR
- n, i, z1, z2, v: INTEGER; ch: CHAR;
- P: Pictures.Picture;
- Map: ARRAY 256 OF BOOLEAN;
- PROCEDURE InitMap;
- VAR r, g, b, i: INTEGER;
- BEGIN
- FOR i:=0 TO 255 DO
- Display.GetColor(i, r, g, b);
- Map[i]:=((r+g+b)DIV 3)>Amiga.PictPrintThresh
- END;
- END InitMap;
- (*PROCEDURE Flip(ch: CHAR): CHAR;
- VAR i, s, d: INTEGER;
- BEGIN
- i := 0; s := ORD(ch); d := 0;
- WHILE i < 8 DO
- IF s MOD 2 = 1 THEN d := d * 2 + 1 ELSE d := d * 2 END;
- s := s DIV 2;
- INC(i)
- END;
- RETURN CHR(d)
- END Flip;*)
- BEGIN
- InitMap;
- Int(bodyR, x); Ch(bodyR, " ");
- Int(bodyR, y); Ch(bodyR, " ");
- Int(bodyR, w); Ch(bodyR, " ");
- Int(bodyR, h); Ch(bodyR, " ");
- Int(bodyR,mode); Str(bodyR, " i");
- i:=0; n:=(w+7) DIV 8;
- adr:=adr+n*h;
- FOR z1:=0 TO h-1 DO
- adr:=adr-n;
- FOR z2:=0 TO n-1 DO
- SYSTEM.GET(adr+z2, ch); (* ch := Flip(ch); *)
- IF i MOD 40 = 0 THEN Ln(bodyR) END ;
- v := (-ORD(ch)-1) MOD 256;
- Hex(bodyR, v DIV 16); Hex(bodyR, v MOD 16);
- INC(i)
- END
- END ;
- w:=((w+7) DIV 8)*8; Ln(bodyR);
- P:=Pictures.ToPrint;
- FOR z2:=0 TO h-1 DO
- FOR z1:=0 TO w-1 BY 4 DO
- v:=0;
- IF Map[Pictures.Get(P, z1, z2)] THEN INC(v,8) END;
- IF Map[Pictures.Get(P, z1+1, z2)] THEN INC(v,4) END;
- IF Map[Pictures.Get(P, z1+2, z2)] THEN INC(v,2) END;
- IF Map[Pictures.Get(P, z1+4, z2)] THEN INC(v,1) END;
- Hex(bodyR, v);
- INC(i);
- IF i = 80 THEN i:=0; Ln(bodyR) END;
- END;
- END;
- Ln(bodyR)
- END Picture;
- PROCEDURE Circle(x0, y0, r: INTEGER);
- BEGIN
- Int(bodyR, x0); Ch(bodyR, " ");
- Int(bodyR, y0); Ch(bodyR, " ");
- Int(bodyR, r); Ch(bodyR, " ");
- Int(bodyR, r); Str(bodyR, " c");
- Ln(bodyR)
- END Circle;
- PROCEDURE Ellipse(x0, y0, a, b: INTEGER);
- BEGIN
- Int(bodyR, x0); Ch(bodyR, " ");
- Int(bodyR, y0); Ch(bodyR, " ");
- Int(bodyR, a); Ch(bodyR, " ");
- Int(bodyR, b); Str(bodyR, " c");
- Ln(bodyR)
- END Ellipse;
- PROCEDURE Line(x0, y0, x1, y1: INTEGER);
- BEGIN
- Int(bodyR, x0); Ch(bodyR, " ");
- Int(bodyR, y0); Ch(bodyR, " ");
- Int(bodyR, x1-x0); Ch(bodyR, " ");
- Int(bodyR, y1-y0); Str(bodyR, " x");
- Ln(bodyR)
- END Line;
- PROCEDURE UseColor(red, green, blue: INTEGER);
- BEGIN
- IF (red # curR) OR (green # curG) OR (blue # curB) THEN
- curR := red; curG := green; curB := blue;
- Int(bodyR, curR); Str(bodyR, " 255 div ");
- Int(bodyR, curG); Str(bodyR, " 255 div ");
- Int(bodyR, curB); Str(bodyR, " 255 div u");
- Ln(bodyR)
- END
- END UseColor;
- (* -- Spline computation -- *)
- PROCEDURE SolveTriDiag(VAR a, b, c, y: RealVector; n: INTEGER);
- VAR i: INTEGER;
- BEGIN (*a, b, c of tri-diag matrix T; solve Ty' = y for y', assign y' to y*)
- i := 1;
- WHILE i < n DO y[i] := y[i] - c[i-1]*y[i-1]; INC(i) END ;
- i := n-1; y[i] := y[i]/a[i];
- WHILE i > 0 DO DEC(i); y[i] := (y[i] - b[i]*y[i+1])/a[i] END
- END SolveTriDiag;
- PROCEDURE OpenSpline(VAR x, y, d: RealVector; n: INTEGER);
- VAR i: INTEGER; d1, d2: REAL;
- a, b, c: RealVector;
- BEGIN (*from x, y compute d = y'*)
- b[0] := 1.0/(x[1] - x[0]); a[0] := 2.0*b[0]; c[0] := b[0];
- d1 := (y[1] - y[0])*3.0*b[0]*b[0]; d[0] := d1; i := 1;
- WHILE i < n-1 DO
- b[i] := 1.0/(x[i+1] - x[i]);
- a[i] := 2.0*(c[i-1] + b[i]);
- c[i] := b[i];
- d2 := (y[i+1] - y[i])*3.0*b[i]*b[i];
- d[i] := d1 + d2; d1 := d2; INC(i)
- END ;
- a[i] := 2.0*b[i-1]; d[i] := d1; i := 0;
- WHILE i < n-1 DO c[i] := c[i]/a[i]; a[i+1] := a[i+1] - c[i]*b[i]; INC(i) END ;
- SolveTriDiag(a, b, c, d, n)
- END OpenSpline;
- PROCEDURE ClosedSpline(VAR x, y, d: RealVector; n: INTEGER);
- VAR i: INTEGER; d1, d2, hn, dn: REAL;
- a, b, c, w: RealVector;
- BEGIN (*from x, y compute d = y'*)
- hn := 1.0/(x[n-1] - x[n-2]);
- dn := (y[n-1] - y[n-2])*3.0*hn*hn;
- b[0] := 1.0/(x[1] - x[0]);
- a[0] := 2.0*b[0] + hn;
- c[0] := b[0];
- d1 := (y[1] - y[0])*3.0*b[0]*b[0]; d[0] := dn + d1;
- w[0] := 1.0; i := 1;
- WHILE i < n-2 DO
- b[i] := 1.0/(x[i+1] - x[i]);
- a[i] := 2.0*(c[i-1] + b[i]);
- c[i] := b[i];
- d2 := (y[i+1] - y[i])*3.0*b[i]*b[i]; d[i] := d1 + d2; d1 := d2;
- w[i] := 0; INC(i)
- END ;
- a[i] := 2.0*b[i-1] + hn; d[i] := d1 + dn;
- w[i] := 1.0; i := 0;
- WHILE i < n-2 DO c[i] := c[i]/a[i]; a[i+1] := a[i+1] - c[i]*b[i]; INC(i) END ;
- SolveTriDiag(a, b, c, d, n-1); SolveTriDiag(a, b, c, w, n-1);
- d1 := (d[0] + d[i])/(w[0] + w[i] + x[i+1] - x[i]); i := 0;
- WHILE i < n-1 DO d[i] := d[i] - d1*w[i]; INC(i) END ;
- d[i] := d[0]
- END ClosedSpline;
- PROCEDURE PrintPoly(VAR p, q: Poly; lim: REAL);
- VAR x0, y0, x1, y1, x2, y2, x3, y3: REAL;
- BEGIN
- x0 := p.d;
- y0 := q.d;
- x1 := x0 + p.c*lim/3.0;
- y1 := y0 + q.c*lim/3.0;
- x2 := x1 + (p.c + p.b*lim)*lim/3.0;
- y2 := y1 + (q.c + q.b*lim)*lim/3.0;
- x3 := x0 + (p.c + (p.b + p.a*lim)*lim)*lim;
- y3 := y0 + (q.c + (q.b + q.a*lim)*lim)*lim;
- Int(bodyR, ENTIER(x1)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(y1)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(x2)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(y2)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(x3)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(y3)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(x0)); Ch(bodyR, " ");
- Int(bodyR, ENTIER(y0)); Str(bodyR, " z");
- Ln(bodyR)
- END PrintPoly;
- PROCEDURE Spline(x0, y0, n, open: INTEGER; VAR X, Y: ARRAY OF INTEGER);
- VAR i: INTEGER; dx, dy, ds: REAL;
- x, xd, y, yd, s: RealVector;
- p, q: PolyVector;
- BEGIN (*from u, v compute x, y, s*)
- x[0] := X[0] + x0; y[0] := Y[0] + y0; s[0] := 0; i := 1;
- WHILE i < n DO
- x[i] := X[i] + x0; dx := x[i] - x[i-1];
- y[i] := Y[i] + y0; dy := y[i] - y[i-1];
- s[i] := ABS(dx) + ABS(dy) + s[i-1]; INC(i)
- END ;
- IF open = 1 THEN OpenSpline(s, x, xd, n); OpenSpline(s, y, yd, n)
- ELSE ClosedSpline(s, x, xd, n); ClosedSpline(s, y, yd, n)
- END ;
- (*compute coefficients from x, y, xd, yd, s*) i := 0;
- WHILE i < n-1 DO
- ds := 1.0/(s[i+1] - s[i]);
- dx := (x[i+1] - x[i])*ds;
- p[i].a := ds*ds*(xd[i] + xd[i+1] - 2.0*dx);
- p[i].b := ds*(3.0*dx - 2.0*xd[i] -xd[i+1]);
- p[i].c := xd[i];
- p[i].d := x[i];
- p[i].t := s[i];
- dy := ds*(y[i+1] - y[i]);
- q[i].a := ds*ds*(yd[i] + yd[i+1] - 2.0*dy);
- q[i].b := ds*(3.0*dy - 2.0*yd[i] - yd[i+1]);
- q[i].c := yd[i];
- q[i].d := y[i];
- q[i].t := s[i]; INC(i)
- END ;
- p[i].t := s[i]; q[i].t := s[i];
- (*print polynomials*)
- i := 0;
- WHILE i < n-1 DO PrintPoly(p[i], q[i], p[i+1].t - p[i].t); INC(i) END
- END Spline;
- PROCEDURE Page(nofcopies: INTEGER);
- BEGIN
- curR := 0; curG := 0; curB := 0;
- Int(bodyR, nofcopies); Str(bodyR, " p"); Ln(bodyR);
- curFont := -1; INC(pno); ppos := Files.Pos(bodyR);
- Str(bodyR, "%%Page: 0 "); Int(bodyR, pno); plen := Files.Pos(bodyR) - ppos; Ln(bodyR)
- END Page;
- PROCEDURE Close;
- CONST bufSize = 4*1024;
- VAR i: INTEGER; printF: Files.File; printR, srcR: Files.Rider; buffer: ARRAY bufSize OF SYSTEM.BYTE;
- cmd: ARRAY 512 OF CHAR;
- BEGIN
- IF ~PrinterDriver.err THEN
- Str(bodyR, "OberonClose"); Ln(bodyR);
- Files.Set(bodyR, bodyF, ppos); (*overwrite last %%Page line*)
- Str(bodyR, "%%Trailer"); DEC(plen, 9); WHILE plen > 0 DO Ch(bodyR, " "); DEC(plen) END;
- cmd:="t:"; Append(cmd, printFileName);
- printF := Files.New(cmd); Files.Set(printR, printF, 0);
- Str(printR, "%!PS-Adobe- minimal conforming"); Ln(printR);
- Str(printR, "%%Creator: Oberon System V4 for Amiga"); Ln(printR);
- Str(printR, "%"); Ln(printR);
- Str(printR, "% Institute for Computer Systems, ETH Zurich, 1990-1995"); Ln(printR);
- Str(printR, "%"); Ln(printR);
- Files.Set(srcR, headerF, 0); Files.ReadBytes(srcR, buffer, bufSize);
- WHILE ~srcR.eof DO Files.WriteBytes(printR, buffer, bufSize); Files.ReadBytes(srcR, buffer, bufSize) END;
- IF srcR.res # bufSize THEN Files.WriteBytes(printR, buffer, bufSize-srcR.res) END;
- i := 0;
- WHILE i <= fontIndex DO DefineFont(printR, fontTable[i]); INC(i) END;
- Str(printR, "OberonInit"); Ln(printR);
- Str(printR, "save"); Ln(printR);
- Str(printR, "%%EndProlog"); Ln(printR); Ln(printR);
- Str(printR, "%%Page: 0 1"); Ln(printR);
- Files.Set(srcR, bodyF, 0); Files.ReadBytes(srcR, buffer, bufSize);
- WHILE ~srcR.eof DO Files.WriteBytes(printR, buffer, bufSize); Files.ReadBytes(srcR, buffer, bufSize) END;
- IF srcR.res # bufSize THEN Files.WriteBytes(printR, buffer, bufSize-srcR.res) END;
- Files.Register(printF);
- (* Files.Set(bodyR, NIL, 0); *)
- headerF := NIL; bodyF := NIL; printF := NIL;
- Kernel.GC(TRUE); (* Release the file immediately *)
- (*
- NOTE:
- In contrary to the Unix implementation, this one does not itself
- treat none as special file name, nor does it delete the file. Its
- up to the command/script OberonPrint to delete the file when
- it is finished with it.
- This procedure will not terminate unless OberonPrint terminates.
- But OberonPrint may choose to spawn a background process for
- printing and return immediately. This module will cycle through
- more than 600 different print file names, thus there shouldn't be
- a problem with reuse of a file name which has not yet finished to
- print.
- *)
- cmd:=''; Amiga.GetSearchPath(cmd);
- Append(cmd,'Script/OberonPrint "');
- Append(cmd,Amiga.PrinterName);
- Append(cmd,'" "');
- Append(cmd,printFileName);
- Append(cmd,'" PSPrinter');
- Amiga.DosCmd(cmd, "NIL:", i);
- IncPrintFile(printFileName)
- END
- END Close;
- PROCEDURE Init*;
- BEGIN
- PrinterDriver.Open := Open;
- PrinterDriver.UseListFont := UseListFont;
- PrinterDriver.ReplConst := ReplConst;
- PrinterDriver.ContString := ContString;
- PrinterDriver.String := String;
- PrinterDriver.ReplPattern := ReplPattern;
- PrinterDriver.Picture := Picture;
- PrinterDriver.Circle := Circle;
- PrinterDriver.Ellipse := Ellipse;
- PrinterDriver.Line := Line;
- PrinterDriver.UseColor := UseColor;
- PrinterDriver.Spline := Spline;
- PrinterDriver.Page := Page;
- PrinterDriver.Close := Close;
- resolution := DefaultResolution
- END Init;
- PROCEDURE SetHeader*;
- VAR s: Texts.Scanner;
- BEGIN
- ScanFirst(s);
- IF s.class IN {Texts.Name, Texts.String} THEN COPY(s.s, headerFileName) END
- END SetHeader;
- BEGIN
- headerFileName := defaultHeaderFileName;
- hexArray := "0123456789ABCDEF";
- resolution := DefaultResolution;
- printFileName:="Oberon.Printfile.aa.ps";
- FontsToMap[0]:="Syntax"; FontsToMap[1]:="Times"; FontsToMap[2]:="Courier";
- styleNames[normal] := ".Roman"; styleNames[bold] := ".Bold";
- styleNames[italic] := ".Italic"; styleNames[magic] := ".Magic"
- END PSPrinter.
-